from flask import Blueprint, render_template, redirect, url_for, flash, request, current_app
from flask_login import login_required, current_user
from app.models import Project, User, Environment, Resource, SystemArchitecture
from app import db
from app.models.equipment import Equipment, ProjectEquipment
import json
from sqlalchemy import or_

bp = Blueprint('main', __name__)

@bp.route('/')
@bp.route('/index')
@login_required
def index():
    return render_template('main/index.html')

@bp.route('/projects')
@login_required
def projects():
    # 获取查询参数
    search = request.args.get('search', '')
    project_type = request.args.get('project_type', '')
    page = request.args.get('page', 1, type=int)
    per_page = 9  # 每页显示9个项目卡片
    
    # 构建查询
    query = Project.query
    if search:
        query = query.filter(
            db.or_(
                Project.name.like(f'%{search}%'),
                Project.project_code.like(f'%{search}%')
            )
        )
    if project_type:
        query = query.filter(Project.project_type == project_type)
    
    # 根据用户角色过滤项目
    if current_user.role == 'engineer':
        query = query.filter_by(creator_id=current_user.id)
    elif current_user.role == 'integrator':
        query = query.filter_by(status='approved')
    
    # 执行分页查询
    pagination = query.order_by(Project.created_at.desc()).paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    return render_template('main/projects.html', 
                         pagination=pagination,
                         search=search,
                         project_type=project_type)

@bp.route('/project/create', methods=['GET', 'POST'])
@login_required
def create_project():
    if current_user.role not in ['engineer', 'manager']:
        flash('只有测控工程师和管理员可以创建项目', 'danger')
        return redirect(url_for('main.projects'))
    
    if request.method == 'POST':
        try:
            # 获取并清理表单数据
            form_data = {
                'name': request.form.get('name', '').strip(),
                'project_code': request.form.get('project_code', '').strip(),
                'project_type': request.form.get('project_type', '').strip(),
                'monitoring_points': request.form.get('monitoring_points', ''),
                'control_loops': request.form.get('control_loops', '')
            }

            # 记录接收到的表单数据
            print(f"Received form data: {form_data}")

            # 验证项目名称
            if not form_data['name']:
                raise ValueError('项目名称不能为空')
            if len(form_data['name']) < 2 or len(form_data['name']) > 128:
                raise ValueError('项目名称长度必须在2-128个字符之间')

            # 验证项目编号
            if not form_data['project_code']:
                raise ValueError('项目编号不能为空')
            if len(form_data['project_code']) < 4 or len(form_data['project_code']) > 64:
                raise ValueError('项目编号长度必须在4-64个字符之间')
            if not form_data['project_code'].isalnum():
                raise ValueError('项目编号只能包含字母和数字')

            # 验证项目类型
            if form_data['project_type'] not in ['industrial', 'environmental']:
                raise ValueError('无效的项目类型')

            # 验证项目编号唯一性
            if Project.query.filter_by(project_code=form_data['project_code']).first():
                raise ValueError('项目编号已存在')

            # 验证并转换数值字段
            try:
                monitoring_points = int(form_data['monitoring_points'])
                control_loops = int(form_data['control_loops'])
            except (ValueError, TypeError):
                raise ValueError('监测点数量和控制回路数量必须为整数')

            if not (1 <= monitoring_points <= 9999):
                raise ValueError('监测点数量必须在1-9999之间')
            if not (1 <= control_loops <= 9999):
                raise ValueError('控制回路数量必须在1-9999之间')

            # 创建新项目
            new_project = Project(
                name=form_data['name'],
                project_code=form_data['project_code'],
                project_type=form_data['project_type'],
                creator_id=current_user.id,
                scale={
                    'monitoring_points': monitoring_points,
                    'control_loops': control_loops
                }
                # status 参数将使用默认值 'draft'
            )

            # 保存到数据库
            db.session.add(new_project)
            db.session.commit()
            print(f"Successfully created project: {new_project.id}")

            flash(f'项目 "{form_data["name"]}" 创建成功', 'success')
            return redirect(url_for('main.project_detail', project_id=new_project.id))

        except ValueError as ve:
            # 处理验证错误
            flash(str(ve), 'danger')
            print(f"Validation error: {str(ve)}")
            return render_template('main/create_project.html', form_data=form_data)

        except Exception as e:
            # 处理其他错误
            db.session.rollback()
            error_msg = str(e)
            print(f"Error creating project: {error_msg}")
            flash(f'创建项目失败: {error_msg}', 'danger')
            return render_template('main/create_project.html', form_data=form_data)

    # GET 请求返回创建表单
    return render_template('main/create_project.html', form_data={})

@bp.route('/profile')
@login_required
def profile():
    return render_template('main/profile.html')

@bp.route('/dashboard')
@login_required
def dashboard():
    return render_template('main/dashboard.html')

@bp.route('/users')
@login_required
def users():
    if current_user.role != 'manager':
        flash('只有管理员可以访问用户管理页面', 'danger')
        return redirect(url_for('main.index'))
    
    # 获取查询参数
    search = request.args.get('search', '')
    role = request.args.get('role', '')
    page = request.args.get('page', 1, type=int)
    per_page = 10  # 每页显示10条记录
    
    # 构建查询
    query = User.query
    if search:
        query = query.filter(
            db.or_(
                User.username.like(f'%{search}%'),
                User.full_name.like(f'%{search}%'),
                User.department.like(f'%{search}%')
            )
        )
    if role:
        query = query.filter(User.role == role)
    
    # 执行分页查询
    pagination = query.order_by(User.id.desc()).paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    return render_template('main/users.html', 
                         pagination=pagination,
                         search=search,
                         role=role)

@bp.route('/user/<int:user_id>')
@login_required
def user_detail(user_id):
    if current_user.role != 'manager':
        flash('只有管理员可以访问用户详情', 'danger')
        return redirect(url_for('main.index'))
    user = User.query.get_or_404(user_id)
    return render_template('main/user_detail.html', user=user)

@bp.route('/user/<int:user_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_user(user_id):
    if current_user.role != 'manager':
        flash('只有管理员可以编辑用户信息', 'danger')
        return redirect(url_for('main.index'))
        
    user = User.query.get_or_404(user_id)
    if request.method == 'POST':
        user.role = request.form.get('role')
        user.department = request.form.get('department')
        user.phone = request.form.get('phone')
        db.session.commit()
        flash('用户信息更新成功', 'success')
        return redirect(url_for('main.user_detail', user_id=user.id))
        
    return render_template('main/edit_user.html', user=user)

@bp.route('/project/<int:project_id>')
@login_required
def project_detail(project_id):
    project = Project.query.get_or_404(project_id)
    
    # 检查访问权限
    if current_user.role not in ['manager', 'engineer'] and \
       (current_user.role == 'engineer' and project.creator_id != current_user.id):
        flash('您没有权限查看此项目', 'danger')
        return redirect(url_for('main.projects'))
        
    return render_template('main/project_detail.html', project=project)

@bp.route('/project/<int:project_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_project(project_id):
    project = Project.query.get_or_404(project_id)
    
    # 检查编辑权限
    if current_user.role != 'manager' and \
       (current_user.role != 'engineer' or project.creator_id != current_user.id):
        flash('您没有权限编辑此项目', 'danger')
        return redirect(url_for('main.projects'))
    
    if request.method == 'POST':
        try:
            # 验证数值字段
            monitoring_points = int(request.form['monitoring_points'])
            control_loops = int(request.form['control_loops'])
            
            if monitoring_points <= 0 or control_loops <= 0:
                flash('监测点数量和控制回路数量必须大于0', 'danger')
                return render_template('main/edit_project.html', project=project)

            project.name = request.form['name']
            project.project_type = request.form['project_type']
            project.scale = {
                'monitoring_points': monitoring_points,
                'control_loops': control_loops
            }
            project.status = request.form['status']
            
            db.session.commit()
            flash('项目更新成功', 'success')
            return redirect(url_for('main.project_detail', project_id=project.id))
            
        except ValueError:
            flash('监测点数量和控制回路数量必须为有效的数字', 'danger')
        except Exception as e:
            db.session.rollback()
            flash('项目更新失败：系统错误', 'danger')
            print(f"Error updating project: {str(e)}")
    
    return render_template('main/edit_project.html', project=project)

@bp.route('/project/<int:project_id>/delete', methods=['POST'])
@login_required
def delete_project(project_id):
    project = Project.query.get_or_404(project_id)
    
    # 检查删除权限
    if current_user.role != 'manager' and \
       (current_user.role != 'engineer' or project.creator_id != current_user.id):
        flash('您没有权限删除此项目', 'danger')
        return redirect(url_for('main.projects'))
    
    try:
        db.session.delete(project)
        db.session.commit()
        flash('项目已成功删除', 'success')
    except Exception as e:
        db.session.rollback()
        flash('项目删除失败：系统错误', 'danger')
        print(f"Error deleting project: {str(e)}")
    
    return redirect(url_for('main.projects'))

@bp.route('/project/<int:project_id>/environment/edit', methods=['GET', 'POST'])
@login_required
def edit_environment(project_id):
    project = Project.query.get_or_404(project_id)
    
    # 检查权限
    if current_user.role != 'manager' and \
       (current_user.role != 'engineer' or project.creator_id != current_user.id):
        flash('您没有权限编辑此项目的环境信息', 'danger')
        return redirect(url_for('main.project_detail', project_id=project_id))
    
    if request.method == 'POST':
        try:
            if not project.environment:
                environment = Environment(project_id=project.id)
                db.session.add(environment)
            else:
                environment = project.environment
            
            environment.temperature_range = request.form.get('temperature_range')
            environment.humidity_range = request.form.get('humidity_range')
            environment.electromagnetic = request.form.get('electromagnetic')
            environment.layout = request.form.get('layout')
            
            db.session.commit()
            flash('环境信息更新成功', 'success')
            return redirect(url_for('main.project_detail', project_id=project.id))
        except Exception as e:
            db.session.rollback()
            flash('环境信息更新失败：系统错误', 'danger')
            print(f"Error updating environment: {str(e)}")
    
    return render_template('main/edit_environment.html', 
                         project=project,
                         environment=project.environment)

@bp.route('/project/<int:project_id>/resource/edit', methods=['GET', 'POST'])
@login_required
def edit_resource(project_id):
    project = Project.query.get_or_404(project_id)
    
    # 检查权限
    if current_user.role != 'manager' and \
       (current_user.role != 'engineer' or project.creator_id != current_user.id):
        flash('您没有权限编辑此项目的资源信息', 'danger')
        return redirect(url_for('main.project_detail', project_id=project_id))
    
    if request.method == 'POST':
        try:
            if not project.resources:
                resource = Resource(project_id=project.id)
                db.session.add(resource)
            else:
                resource = project.resources
            
            resource.budget = float(request.form.get('budget', 0))
            resource.human_resources = {
                'engineers': int(request.form.get('engineers', 0)),
                'technicians': int(request.form.get('technicians', 0))
            }
            resource.equipment = {
                'sensors': {'count': int(request.form.get('sensors', 0)), 'unit': '个'},
                'controllers': {'count': int(request.form.get('controllers', 0)), 'unit': '台'},
                'actuators': {'count': int(request.form.get('actuators', 0)), 'unit': '个'}
            }
            
            db.session.commit()
            flash('资源信息更新成功', 'success')
            return redirect(url_for('main.project_detail', project_id=project.id))
        except ValueError:
            flash('请输入有效的数字', 'danger')
        except Exception as e:
            db.session.rollback()
            flash('资源信息更新失败：系统错误', 'danger')
            print(f"Error updating resource: {str(e)}")
    
    return render_template('main/edit_resource.html', 
                         project=project,
                         resource=project.resources)

@bp.route('/equipment')
@login_required
def equipment_list():
    # 获取查询参数
    search = request.args.get('search', '')
    type = request.args.get('type', '')
    page = request.args.get('page', 1, type=int)
    per_page = 9  # 每页显示9个设备卡片
    
    # 构建查询
    query = Equipment.query
    if search:
        query = query.filter(
            db.or_(
                Equipment.name.like(f'%{search}%'),
                Equipment.model.like(f'%{search}%')
            )
        )
    if type:
        query = query.filter_by(type=type)
    
    # 执行分页查询
    pagination = query.order_by(Equipment.created_at.desc()).paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    return render_template('main/equipment_list.html',
                         pagination=pagination,
                         search=search,
                         type=type)

@bp.route('/equipment/add', methods=['GET', 'POST'])
@login_required
def add_equipment():
    if current_user.role not in ['engineer', 'manager']:
        flash('只有工程师和管理员可以添加设备', 'danger')
        return redirect(url_for('main.equipment_list'))
    
    if request.method == 'POST':
        try:
            # 获取并验证表单数据
            form_data = {
                'name': request.form.get('name', '').strip(),
                'model': request.form.get('model', '').strip(),
                'type': request.form.get('type', '').strip(),
                'manufacturer': request.form.get('manufacturer', '').strip(),
                'price': request.form.get('price', ''),
                'specifications': request.form.get('specifications', '{}')
            }

            # 验证必填字段
            if not form_data['name'] or len(form_data['name']) < 2:
                raise ValueError('设备名称不能为空且长度必须大于2个字符')
            
            if not form_data['model'] or len(form_data['model']) < 2:
                raise ValueError('设备型号不能为空且长度必须大于2个字符')

            if form_data['type'] not in ['sensor', 'controller', 'actuator']:
                raise ValueError('请选择有效的设备类型')

            # 验证并转换价格
            try:
                price = float(form_data['price']) if form_data['price'] else None
                if price is not None and (price < 0 or price > 999999999.99):
                    raise ValueError()
            except ValueError:
                raise ValueError('价格必须是0-999999999.99之间的数字')

            # 验证并解析技术规格
            try:
                specs = json.loads(form_data['specifications'])
                if not isinstance(specs, dict):
                    raise ValueError()
            except (json.JSONDecodeError, ValueError):
                raise ValueError('技术规格格式无效，请使用规格添加功能')

            # 创建新设备
            equipment = Equipment(
                name=form_data['name'],
                model=form_data['model'],
                type=form_data['type'],
                manufacturer=form_data['manufacturer'] or None,
                specifications=specs,
                price=price
            )

            db.session.add(equipment)
            db.session.commit()
            flash('设备添加成功', 'success')
            return redirect(url_for('main.equipment_list'))

        except ValueError as e:
            flash(str(e), 'danger')
            return render_template('main/add_equipment.html', form_data=form_data)
        except Exception as e:
            db.session.rollback()
            flash('设备添加失败：系统错误', 'danger')
            print(f"Error adding equipment: {str(e)}")
            return render_template('main/add_equipment.html', form_data=form_data)

    return render_template('main/add_equipment.html', form_data={})

@bp.route('/equipment/<int:equipment_id>')
@login_required
def equipment_detail(equipment_id):
    equipment = Equipment.query.get_or_404(equipment_id)
    return render_template('main/equipment_detail.html', equipment=equipment)

@bp.route('/equipment/<int:equipment_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_equipment(equipment_id):
    if current_user.role not in ['engineer', 'manager']:
        flash('只有工程师和管理员可以编辑设备', 'danger')
        return redirect(url_for('main.equipment_list'))
        
    equipment = Equipment.query.get_or_404(equipment_id)
    
    if request.method == 'POST':
        try:
            equipment.name = request.form.get('name', '').strip()
            equipment.model = request.form.get('model', '').strip()
            equipment.type = request.form.get('type', '').strip()
            equipment.manufacturer = request.form.get('manufacturer', '').strip()
            
            price = request.form.get('price', '')
            specifications = request.form.get('specifications', '{}')
            
            if price:
                equipment.price = float(price)
            equipment.specifications = json.loads(specifications)
            
            db.session.commit()
            flash('设备更新成功', 'success')
            return redirect(url_for('main.equipment_detail', equipment_id=equipment.id))
            
        except Exception as e:
            db.session.rollback()
            flash('设备更新失败：系统错误', 'danger')
            print(f"Error updating equipment: {str(e)}")
            
    return render_template('main/edit_equipment.html', equipment=equipment)

@bp.route('/equipment/<int:equipment_id>/delete', methods=['POST'])
@login_required
def delete_equipment(equipment_id):
    if current_user.role not in ['engineer', 'manager']:
        flash('只有工程师和管理员可以删除设备', 'danger')
        return redirect(url_for('main.equipment_list'))
    
    equipment = Equipment.query.get_or_404(equipment_id)
    
    try:
        # 检查设备是否已被项目使用
        if ProjectEquipment.query.filter_by(equipment_id=equipment_id).first():
            flash('无法删除已被项目使用的设备', 'danger')
            return redirect(url_for('main.equipment_list'))
        
        db.session.delete(equipment)
        db.session.commit()
        flash('设备删除成功', 'success')
    except Exception as e:
        db.session.rollback()
        flash('设备删除失败：系统错误', 'danger')
        print(f"Error deleting equipment: {str(e)}")
    
    return redirect(url_for('main.equipment_list'))

@bp.route('/architecture/create', methods=['GET', 'POST'])
@login_required
def create_architecture():
    if not current_user.role in ['engineer', 'manager']:
        flash('权限不足', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    if request.method == 'POST':
        try:
            # 获取表单数据
            project_id = request.form.get('project_id')
            name = request.form.get('name', '').strip()
            architecture_type = request.form.get('architecture_type')
            description = request.form.get('description', '').strip()
            
            # 验证必填字段
            if not all([project_id, name, architecture_type]):
                flash('请填写所有必填字段', 'danger')
                return render_template('main/create_architecture.html', 
                                    projects=Project.query.all())
            
            # 验证名称长度
            if len(name) < 2 or len(name) > 128:
                flash('方案名称长度必须在2-128个字符之间', 'danger')
                return render_template('main/create_architecture.html', 
                                    projects=Project.query.all())
            
            # 验证项目存在性和权限
            project = Project.query.get_or_404(project_id)
            if current_user.role != 'manager' and project.creator_id != current_user.id:
                flash('您没有权限为此项目创建架构方案', 'danger')
                return redirect(url_for('main.architecture_list'))
            
            # 解析JSON数据
            try:
                topology = json.loads(request.form.get('topology', '[]'))
                components = json.loads(request.form.get('components', '[]'))
                communication = json.loads(request.form.get('communication', '[]'))
            except json.JSONDecodeError:
                flash('数据格式错误', 'danger')
                return render_template('main/create_architecture.html', 
                                    projects=Project.query.all())
            
            # 创建新的架构方案
            new_architecture = SystemArchitecture(
                project_id=project_id,
                name=name,
                architecture_type=architecture_type,
                description=description,
                topology=topology,
                components=components,
                communication=communication,
                creator_id=current_user.id
            )
            
            db.session.add(new_architecture)
            db.session.commit()
            
            flash('架构方案创建成功', 'success')
            return redirect(url_for('main.architecture_detail', 
                                  architecture_id=new_architecture.id))
            
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f'创建架构方案失败: {str(e)}')
            flash('系统错误，请联系管理员', 'danger')
            return render_template('main/create_architecture.html', 
                                projects=Project.query.all())
    
    # GET 请求，显示创建表单
    return render_template('main/create_architecture.html', 
                         projects=Project.query.all())

@bp.route('/architecture')
@login_required
def architecture_list():
    page = request.args.get('page', 1, type=int)
    per_page = current_app.config.get('ITEMS_PER_PAGE', 10)  # 默认每页显示10条
    
    # 构建查询
    query = SystemArchitecture.query
    
    # 搜索条件
    search_name = request.args.get('name', '').strip()
    search_type = request.args.get('type', '').strip()
    
    if search_name:
        query = query.filter(SystemArchitecture.name.ilike(f'%{search_name}%'))
    if search_type:
        query = query.filter(SystemArchitecture.architecture_type == search_type)
    
    # 权限过滤
    if current_user.role == 'user':
        # 普通用户只能看到自己创建的架构方案
        query = query.filter(SystemArchitecture.creator_id == current_user.id)
    elif current_user.role == 'engineer':
        # 工程师可以看到自己创建的和自己所在项目的架构方案
        project_ids = [p.id for p in Project.query.filter_by(creator_id=current_user.id).all()]
        query = query.filter(or_(
            SystemArchitecture.creator_id == current_user.id,
            SystemArchitecture.project_id.in_(project_ids)
        ))
    # 管理员可以看到所有架构方案
    
    # 排序
    query = query.order_by(SystemArchitecture.updated_at.desc())
    
    # 分页
    pagination = query.paginate(page=page, per_page=per_page)
    architectures = pagination.items
    
    return render_template('main/architecture_list.html',
                         architectures=architectures,
                         pagination=pagination,
                         search_name=search_name,
                         search_type=search_type)

@bp.route('/architecture/<int:architecture_id>/delete', methods=['POST'])
@login_required
def delete_architecture(architecture_id):
    if not current_user.role in ['engineer', 'manager']:
        flash('权限不足', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    architecture = SystemArchitecture.query.get_or_404(architecture_id)
    
    # 检查权限：只有管理员或创建者可以删除
    if current_user.role != 'manager' and architecture.project.creator_id != current_user.id:
        flash('您没有权限删除此架构方案', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    try:
        db.session.delete(architecture)
        db.session.commit()
        flash('架构方案删除成功', 'success')
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f'删除架构方案失败: {str(e)}')
        flash('删除失败：系统错误', 'danger')
    
    return redirect(url_for('main.architecture_list'))

@bp.route('/architecture/<int:architecture_id>')
@login_required
def architecture_detail(architecture_id):
    architecture = SystemArchitecture.query.get_or_404(architecture_id)
    
    # 检查访问权限
    if current_user.role == 'engineer' and architecture.project.creator_id != current_user.id:
        flash('您没有权限查看此架构方案', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    return render_template('main/architecture_detail.html', architecture=architecture)

@bp.route('/architecture/<int:architecture_id>/edit', methods=['GET', 'POST'])
@login_required
def edit_architecture(architecture_id):
    if not current_user.role in ['engineer', 'manager']:
        flash('权限不足', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    architecture = SystemArchitecture.query.get_or_404(architecture_id)
    
    # 检查编辑权限
    if current_user.role != 'manager' and architecture.project.creator_id != current_user.id:
        flash('您没有权限编辑此架构方案', 'danger')
        return redirect(url_for('main.architecture_list'))
    
    if request.method == 'POST':
        try:
            # 获取表单数据
            name = request.form.get('name', '').strip()
            architecture_type = request.form.get('architecture_type')
            description = request.form.get('description', '').strip()
            
            # 验证必填字段
            if not all([name, architecture_type]):
                flash('请填写所有必填字段', 'danger')
                return render_template('main/edit_architecture.html', 
                                    architecture=architecture)
            
            # 验证方案名称长度
            if len(name) < 2 or len(name) > 128:
                flash('方案名称长度必须在2-128个字符之间', 'danger')
                return render_template('main/edit_architecture.html', 
                                    architecture=architecture)
            
            # 解析JSON数据
            try:
                topology = json.loads(request.form.get('topology', '[]'))
                components = json.loads(request.form.get('components', '[]'))
                communication = json.loads(request.form.get('communication', '[]'))
            except json.JSONDecodeError:
                flash('数据格式错误', 'danger')
                return render_template('main/edit_architecture.html', 
                                    architecture=architecture)
            
            # 更新架构方案
            architecture.name = name
            architecture.architecture_type = architecture_type
            architecture.description = description
            architecture.topology = topology
            architecture.components = components
            architecture.communication = communication
            
            db.session.commit()
            flash('架构方案更新成功', 'success')
            return redirect(url_for('main.architecture_detail', architecture_id=architecture.id))
            
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f'更新架构方案失败: {str(e)}')
            flash('系统错误，请联系管理员', 'danger')
            return render_template('main/edit_architecture.html', 
                                architecture=architecture)
    
    return render_template('main/edit_architecture.html', architecture=architecture) 